package com.beantools.util.jsonutil;

import com.alibaba.fastjson.JSONObject;
import com.beantools.execption.JSONException;
import com.beantools.file.JsonFile;

import java.io.IOException;
import java.util.List;

import static com.beantools.util.StringUtil.isBlank;

/**
 * 这是处理<code>json</code>对象的工具类，比如，调用者可以将<code>jsonObject</code>对象，
 * 或者<code>List</code>容器对象，或者<code>javabean</code>对象存储到文件当中。
 * <p>
 * 这个工具将在以后的公司开发的插件中使用。
 *
 * @author baoya
 * @version 1.0
 * @since 1.1.0
 */
@SuppressWarnings("all")
public class JSONExportUtil extends JSONUtil {

    /**
     * 这是将实例化的对象<code>objects</code>集合写进文件中，如果调用者没有写文件名<code>fileName</code>，
     * 就以当前的这种格式的时间<strong>yyyyMMddHHmmss</strong>作为文件名。
     * <p>
     * 同时，该方法有个<code>relativePath</code>参数，这是相对于项目的路径，例如<strong>src\test\java\com\beantools\file</strong>
     * 其不用添加文件名称。
     * 请参考测试代码{@link com.beantools.util.jsonutil.JSONExportTest#testExportJsonOne()}
     *
     * @param objects      待导出的文件对象的集合
     * @param relativePath 导出文件的相对路径，比如<strong>src\test\java\com\beantools\file</strong>
     * @param fileName     文件名称
     * @return 如果导出成文件成功，则返回true
     */
    public static boolean exportRelativeFile(List<Object> objects, String relativePath, String fileName) {
        return exportRelativeFile(getJsonString(objects), relativePath, fileName);
    }

    /**
     * 这是将实例化的对象<code>objects</code>集合写进文件中，如果调用者没有写文件名<code>fileName</code>，
     * 就以当前的这种格式的时间<strong>yyyyMMddHHmmss</strong>作为文件名。
     * <p>
     * 同时，该方法有个<code>relativePath</code>参数，其是布尔类型，来判断输出文件的路径。如果{@code relativePath}
     * 是true，<code>path</code>就是相对路径，否则，就是绝对路径。
     * <p>
     * 请参考测试代码{@link com.beantools.util.jsonutil.JSONExportTest#testExportJsonTwo()}
     *
     * @param objects      待导出的文件对象的集合
     * @param path         导出文件的路径，比如<strong>src\test\java\com\beantools\file</strong>
     * @param relativePath 这是布尔类型，可以和<code>path</code>共同使用，如果<code>relativePath = true</code>
     *                     <code>path</code>是相对路径，反之，是绝对路径
     * @param fileName     导出文件的名称
     * @return 如果导出成文件成功，则返回true
     */
    public static boolean exportFile(List<Object> objects, String path, boolean relativePath, String fileName) {
        return exportFile(getJsonString(objects), path, relativePath, fileName);
    }

    /**
     * 这是将实例化的对象<code>objects</code>集合写进文件中，以当前的这种格式的时间<strong>yyyyMMddHHmmss</strong>作为文件名。
     * <p>
     * 如下代码所示：
     * 请参考测试代码{@link com.beantools.util.jsonutil.JSONExportTest#testExportJsonThree()}
     *
     * @param objects 待导出的文件对象的集合
     * @param path    导出文件的绝对路径，比如<strong>C:\\Users\\Administrator\\Desktop</strong>
     * @return 如果导出成文件成功，则返回true
     */
    public static <T> boolean exportAbsoluteFile(List<T> objects, String path) {
        return exportAbsoluteFile(getJsonString(objects), path);
    }

    /**
     * 这是将实例化的对象<code>object</code>集合写进文件中，如果调用者没有写文件名<code>fileName</code>，
     * 就以当前的这种格式的时间<strong>yyyyMMddHHmmss</strong>作为文件名。
     * <p>
     * 同时，该方法有个<code>relativePath</code>参数，这是相对于项目的路径，例如<strong>src\test\java\com\beantools\file</strong>
     * 其不用添加文件名称。
     * <p>
     * 请参考测试代码{@link com.beantools.util.jsonutil.JSONExportTest#testExportJsonFour()}
     *
     * @param object       待导出的文件对象的集合
     * @param relativePath 导出文件的相对路径，比如<strong>src\\test\\java\\com\\beantools\\file</strong>
     * @param fileName     导出文件的名称。如果调用者不传名称，或者名称为空，则默认是时间格式的名称
     * @return 如果导出成文件成功，则返回true
     */
    public static <T> boolean exportRelativeFile(T object, String relativePath, String fileName) {
        return exportRelativeFile(getJsonString(object), relativePath, fileName);
    }

    /**
     * 这是将实例化的对象<code>object</code>集合写进文件中，如果调用者没有写文件名<code>fileName</code>，
     * 就以当前的这种格式的时间<strong>yyyyMMddHHmmss</strong>作为文件名。
     * <p>
     * 同时，该方法有个<code>relativePath</code>参数，其是布尔类型。如果<code>relativePath</code>为true，
     * 则<code>path</code>为相对路径，比如<strong>src\\test\\java\\com\\beantools\\file</strong>，如果
     * 如果<code>relativePath</code>为false，则<code>path</code>为绝对路径，比如<strong>C:\Users\Administrator\Desktop</strong>
     * <p>
     * 如下代码所示：
     * 请参考测试代码{@link com.beantools.util.jsonutil.JSONExportTest#testExportJsonFive()}
     *
     * @param object       待导出的文件对象的集合
     * @param path         这是文件的路径
     * @param relativePath 这是布尔类型，用来判断导出文件的路径
     * @param fileName     导出文件的名称。如果调用者不传名称，或者名称为空，则默认是时间格式的名称
     * @return 如果导出成文件成功，则返回true
     */
    public static <T> boolean exportFile(T object, String path, boolean relativePath, String fileName) {
        return exportFile(getJsonString(object), path, relativePath, fileName);
    }

    /**
     * 这是将实例化的对象<code>object</code>写进文件中，以当前的这种格式的时间<strong>yyyyMMddHHmmss</strong>作为文件名。
     * <p>
     * 该方法有个<code>path</code>参数，导出文件的绝对路径，例如<strong>C:\Users\Administrator\Desktop</strong>
     * 请参考测试代码{@link com.beantools.util.jsonutil.JSONExportTest#testExportJsonSix()}
     *
     * @param object 待导出的文件对象的集合
     * @param path   导出文件的绝对路径，比如<strong>C:\\Users\\Administrator\\Desktop</strong>
     * @return 如果导出成文件成功，则返回true
     */
    public static boolean exportAbsoluteFile(Object object, String path) {
        return exportAbsoluteFile(getJsonString(object), path);
    }

    /**
     * 这是将实例化的对象<code>jsonObject</code>集合写进文件中，如果调用者没有写文件名<code>fileName</code>，
     * 就以当前的这种格式的时间<strong>yyyyMMddHHmmss</strong>作为文件名。
     * <p>
     * 同时，该方法有个<code>relativePath</code>参数，这是相对于项目的路径，例如<strong>src\test\java\com\beantools\file</strong>
     * 其不用添加文件名称。
     * 请参考测试代码{@link com.beantools.util.jsonutil.JSONExportTest#testExportJsonSeven()}
     *
     * @param jsonObject   <code>JsonObject</code>的实例化对象
     * @param relativePath 导出文件的相对路径，比如<strong>C:\\Users\\Administrator\\Desktop</strong>
     * @param fileName     导出的文件名称
     * @return 如果导出成文件成功，则返回true
     */
    public static boolean exportRelativeFile(JSONObject jsonObject, String relativePath, String fileName) {
        return exportRelativeFile(getJsonString(jsonObject), relativePath, fileName);
    }

    /**
     * 这是将实例化的对象<code>jsonObject</code>集合写进文件中，如果调用者没有写文件名<code>fileName</code>，
     * 就以当前的这种格式的时间<strong>yyyyMMddHHmmss</strong>作为文件名。
     * <p>
     * 同时，该方法有个<code>relativePath</code>参数，其是布尔类型。如果<code>relativePath</code>为true，
     * 则<code>path</code>为相对路径，比如<strong>src\\test\\java\\com\\beantools\\file</strong>，如果
     * 如果<code>relativePath</code>为false，则<code>path</code>为绝对路径，比如<strong>C:\Users\Administrator\Desktop</strong>
     * <p>
     * 请参考测试代码{@link com.beantools.util.jsonutil.JSONExportTest#testExportJsonEight()}
     *
     * @param jsonObject   <code>JsonObject</code>的实例化对象
     * @param path         这是文件的路径
     * @param relativePath 这是布尔类型，用来判断导出文件的路径
     * @param fileName     导出文件的名称。如果调用者不传名称，或者名称为空，则默认是时间格式的名称
     * @return 如果导出成文件成功，则返回true
     */
    public static boolean exportFile(JSONObject jsonObject, String path, boolean relativePath, String fileName) {
        return exportFile(getJsonString(jsonObject), path, relativePath, fileName);
    }

    /**
     * 这是将实例化的对象<code>jsonObject</code>写进文件中，以当前的这种格式的时间<strong>yyyyMMddHHmmss</strong>作为文件名。
     * <p>
     * 该方法有个<code>path</code>参数，导出文件的绝对路径，例如<strong>C:\Users\Administrator\Desktop</strong>
     * 请参考测试代码{@link com.beantools.util.jsonutil.JSONExportTest#testExportJsonNine()}
     *
     * @param jsonObject <code>JsonObject</code>的实例化对象
     * @param path       导出文件的绝对路径，比如<strong>C:\\Users\\Administrator\\Desktop</strong>
     * @return 如果导出成文件成功，则返回true
     */
    public static boolean exportAbsoluteFile(JSONObject jsonObject, String path) {
        return exportAbsoluteFile(getJsonString(jsonObject), path);
    }

    /**
     * 这是将<code>json</code>字符串写进文件中，如果调用者没有写文件名<code>fileName</code>，
     * 就以当前的这种格式的时间<strong>yyyyMMddHHmmss</strong>作为文件名。
     * <p>
     * 同时，该方法有个<code>relativePath</code>参数，这是相对于项目的路径，例如<strong>src\test\java\com\beantools\file</strong>
     * 其不用添加文件名称。
     * 请参考测试代码{@link com.beantools.util.jsonutil.JSONExportTest#testExportJsonTen()}
     *
     * @param json         <code>json</code>的字符串
     * @param relativePath 导出文件的相对路径，比如<strong>src\\test\\java\\com\\beantools\\file</strong>
     * @param fileName     导出的文件名称
     * @return 如果导出成文件成功，则返回true
     */
    public static boolean exportRelativeFile(String json, String relativePath, String fileName) {
        if (isBlank(json)) {
            throw new JSONException("空对象，导出异常");
        }
        try {
            return JsonFile.getInstance(json).exportFormatByRelativePath(relativePath, fileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 这是将<code>json</code>字符串写进文件中，如果调用者没有写文件名<code>fileName</code>，
     * 就以当前的这种格式的时间<strong>yyyyMMddHHmmss</strong>作为文件名。
     * <p>
     * 同时，该方法有个<code>relativePath</code>参数，其是布尔类型。如果<code>relativePath</code>为true，
     * 则<code>path</code>为相对路径，比如<strong>src\\test\\java\\com\\beantools\\file</strong>，如果
     * 如果<code>relativePath</code>为false，则<code>path</code>为绝对路径，比如<strong>C:\Users\Administrator\Desktop</strong>
     * <p>
     * 请参考测试代码{@link com.beantools.util.jsonutil.JSONExportTest#testExportJsonEleven()}
     *
     * @param json         <code>json</code>的字符串
     * @param filePath     这是文件的路径
     * @param relativePath 这是布尔类型，用来判断导出文件的路径
     * @param fileName     导出文件的名称。如果调用者不传名称，或者名称为空，则默认是时间格式的名称
     * @return 如果导出成文件成功，则返回true
     */
    public static boolean exportFile(String json, String filePath, boolean relativePath, String fileName) {
        if (isBlank(json)) {
            throw new JSONException("空对象，导出异常");
        }
        try {
            return JsonFile.getInstance(json).exportFormat(filePath, fileName, relativePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 这是将<code>json</code>字符串写进文件中，以当前的这种格式的时间<strong>yyyyMMddHHmmss</strong>作为文件名。
     * <p>
     * 该方法有个<code>path</code>参数，导出文件的绝对路径，例如<strong>C:\Users\Administrator\Desktop</strong>
     * 请参考测试代码{@link com.beantools.util.jsonutil.JSONExportTest#testExportJsonTwelve()}
     *
     * @param json <code>json</code>的字符串
     * @param path 导出文件的绝对路径，比如<strong>C:\\Users\\Administrator\\Desktop</strong>
     * @return 如果导出成文件成功，则返回true
     */
    public static boolean exportAbsoluteFile(String json, String path) {
        if (isBlank(json)) {
            throw new JSONException("空对象，导出异常");
        }
        JsonFile instance = JsonFile.getInstance(json);
        try {
            return instance.exportFormatByAbsolutePath(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}
